package fudan.se.project.service.infrastructure.func.conference.action.pcmember;


import fudan.se.project.controller.request.ReviewInfoSubmitRequest;
import fudan.se.project.domain.conference.Conference;
import fudan.se.project.domain.conference.Conference.ConferenceStage;
import fudan.se.project.domain.conference.post.Post;
import fudan.se.project.domain.conference.production.Paper;
import fudan.se.project.domain.conference.production.Paper.PaperState;
import fudan.se.project.domain.conference.production.ReviewInfo;
import fudan.se.project.service.infrastructure.entity.conference.ConferenceService;
import fudan.se.project.service.infrastructure.entity.conference.post.PostService;
import fudan.se.project.service.infrastructure.entity.conference.production.PaperService;
import fudan.se.project.service.infrastructure.entity.conference.production.ReviewInfoService;
import org.springframework.stereotype.Service;

import java.util.Set;

import static fudan.se.project.domain.conference.production.ReviewInfo.ReviewConfidence;
import static fudan.se.project.domain.conference.production.ReviewInfo.ReviewInfoState;

@Service
public class ReviewInfoSubmitService {

    private final ReviewInfoService reviewInfoService;
    private final PaperService paperService;
    private final ConferenceService conferenceService;
    private final PostService postService;

    public ReviewInfoSubmitService(
            ReviewInfoService reviewInfoService,
            PaperService paperService,
            ConferenceService conferenceService,
            PostService postService
    ) {
        this.reviewInfoService = reviewInfoService;
        this.paperService = paperService;
        this.conferenceService = conferenceService;
        this.postService = postService;
    }


    public boolean process(
            ReviewInfo reviewInfo,
            ReviewInfoSubmitRequest request) {

        if (reviewInfo.isCompleted()) {
            return false;
        }

        reviewInfo.setCompleted(true);
        reviewInfo.setComment(request.getComment());

        int confidence = request.getReviewConfidence();
        int state = request.getReviewInfoState();

        if (confidence < 0 || state < 0
                || confidence >= ReviewConfidence.values().length
                || state >= ReviewInfoState.values().length
        ) {
            return false;
        }

        reviewInfo.setReviewConfidence(ReviewConfidence.values()[confidence]);
        reviewInfo.setReviewInfoState(ReviewInfoState.values()[state]);

        reviewInfo = reviewInfoService.save(reviewInfo);

        Paper paper = reviewInfo.getPaper();
        if (checkAllReviewInfosIsCompleted(paper.getReviewInfos())) {
            paper.setPaperState(PaperState.COMPLETED);
            paper = paperService.save(paper);
            Post post = new Post(paper, "post:" + paper.getTitleText());
            postService.save(post);
        }


        Conference conference = paper.getConference();
        if (paper.getPaperState().equals(PaperState.COMPLETED)
                && checkAllPapersIsCompleted(conference.getPapers())
        ) {
            conference.setStage(ConferenceStage.REVIEW_END);
            conferenceService.save(conference);
        }

        return true;

    }

    private boolean checkAllPapersIsCompleted(Set<Paper> papers) {
        for (Paper paper : papers) {
            if (!paper.getPaperState().equals(PaperState.COMPLETED)) {
                return false;
            }
        }
        return true;
    }

    private boolean checkAllReviewInfosIsCompleted(Set<ReviewInfo> reviewInfos) {
        for (ReviewInfo reviewInfo : reviewInfos) {
            if (!reviewInfo.isCompleted()) {
                return false;
            }
        }
        return true;
    }

}
